package com.xbongbong.crm.perform.query.list.business;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.help.FormDataFormExplainHelper;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.TelephoneMaskUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.abstracts.AbstractSpecialDataAnalysisHelp;
import com.xbongbong.parent.parse.data.FormDataListAnalysisDataHelp;
import com.xbongbong.pro.customer.pojo.CustomerMainContactPojo;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.form.pojo.dto.FormConfigGetDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author 吴峰
 * @version v1.0
 * @date 2020/4/16 16:32
 * @since v1.0
 */
@Component
public class CustomerSpecialDataHandle extends AbstractSpecialDataAnalysisHelp {

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FormDataFormExplainHelper formDataFormExplainHelper;
    @Resource
    private EsHelper esHelper;
    @Resource
    private FormDataListAnalysisDataHelp formDataListAnalysisDataHelp;

    @Override
    public Integer businessType() {
        return XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
    }

    @Override
    public CustomerMainContactPojo getSpecialData(FormDataListDTO formDataListDTO, PaasFormDataEsListVO formDataEsListVO) throws XbbException {
        List<Long> dataIdIn = new ArrayList<>();
        formDataEsListVO.getPaasFormDataESList().forEach(item->{
            dataIdIn.add(item.getDataId());
        });
        CustomerMainContactPojo customerMainContactPojo = newAnalysisContactForCustomer(formDataListDTO.getCorpid(), formDataListDTO, dataIdIn, formDataEsListVO.getHeadList());
        FormConfigGetDTO formConfigGetDTO = new FormConfigGetDTO();
        formConfigGetDTO.setCorpid(formDataListDTO.getCorpid());
        formConfigGetDTO.setBusinessType(formDataListDTO.getBusinessType());
        formConfigGetDTO.setFormId(formDataListDTO.getFormId());
        Map<String, String> lastConnectTimeMap = formDataListAnalysisDataHelp.lastConnectTime(formConfigGetDTO);
        customerMainContactPojo.setLastConnectTimeMap(lastConnectTimeMap);
        return customerMainContactPojo;
    }

    @Override
    public void setSpecialData(JSONObject resultObject, Long dataId, CustomerMainContactPojo customerMainContactPojo, PaasFormDataEsListVO formDataEsListVO, UserVO loginUser) throws XbbException {
        Map<String, FieldAttrEntity> explainMap = formDataEsListVO.getExplainMap();
        Integer isPublic = getIntegerOrDefaultFromFormData(resultObject, CustomerManagementEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
        // 系统字段才去解析
        Map<Long, Object> nameMap = customerMainContactPojo.getNameMap();
        // 主联系人的attr可能被占用了，所以这边要判断下
        if (!nameMap.isEmpty() && explainMap.containsKey(CustomerManagementEnum.CONTACT_NAME.getAttr())
                && Objects.equals(0, explainMap.get(CustomerManagementEnum.CONTACT_NAME.getAttr()).getIsRedundant())) {
            resultObject.put(CustomerManagementEnum.CONTACT_NAME.getAttr(), nameMap.getOrDefault(dataId, ""));
        }
        Map<Long, JSONArray> phoneMap = customerMainContactPojo.getPhoneMap();
        if (!phoneMap.isEmpty()) {
            FieldAttrEntity customerPhone = explainMap.get(CustomerManagementEnum.PHONE.getAttr());
            Integer customerShowPublicPool = 0;
            Integer customerPublicPool = 0;
            if (Objects.nonNull(customerPhone)) {
                customerShowPublicPool = customerPhone.getShowPublicPool();
                customerPublicPool = customerPhone.getPublicPool();
            }
            FieldAttrEntity phoneAttr = customerMainContactPojo.getPhoneAttr();
            Integer publicPool = phoneAttr.getPublicPool();
            Integer showPublicPool = phoneAttr.getShowPublicPool();
            // 系统字段才去解析
            if (Objects.equals(isPublic, BasicConstant.ONE) && Objects.equals(showPublicPool, BasicConstant.ONE) && Objects.equals(publicPool, BasicConstant.ZERO)) {
                // 如果联系人模板电话字段配置了公海池不可见，那么公海客户的主联系人电话不可见
                resultObject.put(CustomerManagementEnum.CONTACT_PHONE.getAttr(), new JSONArray());
            } else {
                if (Objects.isNull(loginUser) || loginUser.isAdminOrBoss()) {
                    //管理员和老板不受电话掩码设置影响
                    resultObject.put(CustomerManagementEnum.CONTACT_PHONE.getAttr(), phoneMap.getOrDefault(dataId, new JSONArray()));
                } else {
                    try {
                        FieldAttrEntity contactPhoneField = phoneAttr.getSubForm().getItems().stream().filter(item -> Objects.equals(item.getAttr(), "text_2")).findFirst().orElse(null);
                        Integer isMaskTelephone = Objects.nonNull(contactPhoneField) ? contactPhoneField.getIsMaskTelephone() : 0;
                        JSONArray phoneArray = phoneMap.getOrDefault(dataId, new JSONArray());
                        for (int i = 0; i < phoneArray.size(); i++) {
                            JSONObject phoneObj = phoneArray.getJSONObject(i);
                            String telephoneNumber = phoneObj.getString("text_2");
                            if (StringUtil.isNotEmpty(telephoneNumber) && Objects.equals(isMaskTelephone, BasicConstant.ONE)) {
                                //掩码处理后的电话号码
                                String maskTelephoneCode = TelephoneMaskUtil.maskTelephone(telephoneNumber);
                                phoneObj.put("text_2", maskTelephoneCode);
                            }
                        }
                        resultObject.put(CustomerManagementEnum.CONTACT_PHONE.getAttr(), phoneArray);
                    } catch (Exception e) {
                        resultObject.put(CustomerManagementEnum.CONTACT_PHONE.getAttr(), phoneMap.getOrDefault(dataId, new JSONArray()));
                    }
                }
            }
            if (Objects.equals(isPublic, BasicConstant.ONE) && Objects.equals(customerShowPublicPool, BasicConstant.ONE) && Objects.equals(customerPublicPool, BasicConstant.ZERO)) {
                // 如果客户模板电话字段配置了公海池不可见，那么公海客户的电话不可见
                resultObject.put(CustomerManagementEnum.PHONE.getAttr(), new JSONArray());
            }
        }
    }

    /**
     * 获取客户主联系人电话权限
     *
     * @param corpid 公司id
     * @param formDataListDTO 入参
     * @param customerIds 客户ids
     * @return
     * @throws
     * @author hongxiao
     * @date 2019-08-07 15:45
     * @since v1.0
     * @version v1.0
     */
    public CustomerMainContactPojo newAnalysisContactForCustomer(String corpid, FormDataListDTO formDataListDTO, List<Long> customerIds, List<FieldAttrEntity> customerFieldList) throws XbbException {
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(XbbRefTypeEnum.CONTACT.getCode(), corpid);
        if (paasFormExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        CustomerMainContactPojo customerMainContactPojo = new CustomerMainContactPojo();
        UserVO loginUser = formDataListDTO.getLoginUser();
        if(!loginUser.isAdminOrBoss() && !loginUser.getPermSet().contains(ProPermissionAliasEnum.CONTACT_VIEW.getAlias())){
            customerMainContactPojo.setCustomerFieldList(customerFieldList);
            return customerMainContactPojo;
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach(item -> {
            explainMap.put(item.getAttr(), item);
        });
        FieldAttrEntity phoneEntity = explainMap.get(ContactEnum.PHONE.getAttr());
        List<FieldAttrEntity> jsonArray = new ArrayList<>();
        List<? extends FieldAttrEntity> phoneJsonArray = phoneEntity.getSubForm().getItems();
        for (int i = 0; i < phoneJsonArray.size(); i++) {
            FieldAttrEntity jsonObject = phoneJsonArray.get(i);
            if (Objects.equals("text_1", jsonObject.getAttr()) || Objects.equals("text_2", jsonObject.getAttr())){
                jsonArray.add(jsonObject);
            }
        }
        customerFieldList.forEach(item->{
            if (Objects.equals(item.getAttr(), CustomerManagementEnum.CONTACT_PHONE.getAttr()) && Objects.equals(item.getIsRedundant(), 0)) {
                //20177 【成功部】联系人联系方式类型修改后，主联系人类型没有同步
                SubFormPoJo subFormPoJo = new SubFormPoJo();
                subFormPoJo.setItems(jsonArray);
                item.setSubForm(subFormPoJo);
            }
        });
        List<String> customerIdIn = new ArrayList<>();
        for(Long customerId : customerIds) {
            customerIdIn.add(customerId.toString());
        }
        // 数据
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        // 添加corpid,formId,del
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", DelEnum.NORMAL.getDel()));
        //无需审批和通过
        boolQueryBuilder.filter(termsQuery("flowStatus", FlowStatusEnum.getStatisticType()));
        boolQueryBuilder.filter(termsQuery(ContactEnum.getEsAttr4Keyword(ContactEnum.CUSTOMER_NAME), customerIdIn));
        boolQueryBuilder.filter(termQuery(ContactEnum.getEsAttr4Keyword(ContactEnum.IS_MAIN), BasicConstant.ONE));

        // 客户id，联系人电话，创建人，负责人，联系人id
        List<String> fieldList = new ArrayList<>();
        fieldList.add("data." + ContactEnum.CUSTOMER_NAME.getAttr());
        fieldList.add("data." + ContactEnum.NAME.getAttr());
        fieldList.add("data." + ContactEnum.PHONE.getAttr());
        fieldList.add(ContactEnum.CREATOR_ID.getAttr());
        fieldList.add("data." + ContactEnum.OWNER_ID.getAttr());
        fieldList.add(FieldTypeEnum.DATAID.getAlias());

        XbbAggregatedPage aggregatedPage;
        try {
            aggregatedPage = esHelper.findByPage(IndexTypeEnum.IDX_SAAS_CONTACT, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList, 1, formDataListDTO.getPageSize() * 3, null);
        } catch (XbbException e) {
            aggregatedPage = null;
        }
        if (Objects.isNull(aggregatedPage)) {
            customerMainContactPojo.setCustomerFieldList(customerFieldList);
            return customerMainContactPojo;
        }
        List<PaasFormDataEntityExt> formDataEsList = aggregatedPage.getContent();
        if(formDataEsList.isEmpty()) {
            customerMainContactPojo.setCustomerFieldList(customerFieldList);
            return customerMainContactPojo;
        }

        List<Long> dataIdList = new ArrayList<>();
        for(PaasFormDataEntityExt item: formDataEsList) {
            dataIdList.add(item.getDataId());
        }
        //协同团队
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        formDataFormExplainHelper.getUserIdMap(dataIdList,corpid,XbbRefTypeEnum.CONTACT.getCode(),false,mainUserMap,coUserMap);

        customerMainContactPojo.setCustomerFieldList(customerFieldList);
        customerMainContactPojo.setPhoneAttr(phoneEntity);
        Map<String, FieldAttrEntity> subPhoneMap = ExplainUtil.getExplainMapByList(phoneEntity.getSubForm().getItems());
        FieldAttrEntity subPhone = subPhoneMap.get("text_2");
        FieldAttrEntity type = subPhoneMap.get("text_1");
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO);

        Map<Long, Object> nameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, JSONArray> phoneMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt paasFormDataEsEntity: formDataEsList){

            handlerExplainDTO.setCreatorId(paasFormDataEsEntity.getCreatorId());
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(paasFormDataEsEntity.getDataId(), new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(paasFormDataEsEntity.getDataId(), new ArrayList<>()));

            JSONObject dataJsonObject = paasFormDataEsEntity.getData();
            boolean hidePhoneFlag = ExplainUtil.fieldAttrHide(phoneEntity, handlerExplainDTO);
            nameMap.put(paasFormDataEsEntity.getData().getLong(ContactEnum.CUSTOMER_NAME.getAttr()), dataJsonObject.get(ContactEnum.NAME.getAttr()));

            if (hidePhoneFlag) {
                phoneMap.put(dataJsonObject.getLong(ContactEnum.CUSTOMER_NAME.getAttr()), new JSONArray());
            } else {
                hidePhoneFlag = ExplainUtil.fieldAttrHide(subPhone, handlerExplainDTO);
                JSONArray resultArray = new JSONArray();
                JSONArray subPhoneArray = dataJsonObject.getJSONArray(ContactEnum.PHONE.getAttr());
                if (Objects.nonNull(subPhoneArray)) {
                    for (int i = 0; i < subPhoneArray.size(); i++) {
                        JSONObject result = new JSONObject();
                        JSONObject jsonObject = subPhoneArray.getJSONObject(i);
                        result.put("text_2", jsonObject.get("text_2"));
                        if (hidePhoneFlag) {
                            result.put("text_2", "****");
                        }
                        result.put("text_1", ItemUtil.getCommonItem(type, jsonObject));
                        resultArray.add(result);
                    }
                }
                phoneMap.put(dataJsonObject.getLong(ContactEnum.CUSTOMER_NAME.getAttr()), resultArray);
            }
        }
        customerMainContactPojo.setNameMap(nameMap);
        customerMainContactPojo.setPhoneMap(phoneMap);
        return customerMainContactPojo;
    }
}
